package com.shineoxygen.common.base.alipay.directpay.web;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.shineoxygen.common.base.alipay.directpay.enums.PayStatus;
import com.shineoxygen.common.base.alipay.directpay.utils.AlipayNotify;
import com.shineoxygen.common.base.controller.BaseController;

/**
 * 
 * @author 王辉阳
 * @date 2016年11月18日 下午11:59:43
 * @Description 即时到账通知封装：
 * 
 */
@Controller
public abstract class AliPayController extends BaseController {
	/**
	 * 同步通知跳转业务逻辑：本地有支付状态则必须同步更新
	 * 
	 * @param payStatus
	 *            null表示验证失败，通知非法
	 * @return 跳转的视图
	 */
	protected abstract String returnHandler(PayStatus payStatus, ModelMap modelMap);

	/**
	 * 异步通知业务逻辑：本地有支付状态则必须同步更新
	 * 
	 * @param payStatus
	 *            null表示验证失败
	 */
	protected abstract void notifyHandlerl(PayStatus payStatus);

	/**
	 * 即时到账支付同步通知
	 * 
	 * @param out_trade_no
	 *            商户订单号
	 * @param trade_no
	 *            支付宝交易号
	 * @param trade_status
	 *            交易状态
	 * @param request
	 */
	@RequestMapping("/returnURL")
	public String returnURL(String out_trade_no, String trade_no, String trade_status, HttpServletRequest request, ModelMap modelMap) {
		// TODO 库中支付状态接受到通知更新后，以此次通知为准，因为要跳转页面
		// 获取支付宝GET过来反馈信息，校验来源
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}

		boolean verify_result = AlipayNotify.verify(params);

		if (verify_result) {// 验证成功：只有两个状态值
			if (trade_status.equals(PayStatus.TRADE_SUCCESS.name())) {
				return returnHandler(PayStatus.TRADE_SUCCESS, modelMap);
			}
			if (trade_status.equals(PayStatus.TRADE_FINISHED.name())) {
				return returnHandler(PayStatus.TRADE_FINISHED, modelMap);
			}
		}
		return returnHandler(null, modelMap);
	}

	/**
	 * 
	 * 异步通知，默认返回状态只有TRADE_FINISHED ，TRADE_SUCCESS两种，其他可以商户申请
	 * 
	 * @param out_trade_no
	 *            商户订单号
	 * @param trade_no
	 *            支付宝交易号
	 * @param trade_status
	 *            交易状态
	 * @param request
	 * @throws IOException
	 */
	@RequestMapping("/notifyURL")
	public void notifyURL(String out_trade_no, String trade_no, String trade_status, HttpServletRequest request, HttpServletResponse res) throws IOException {
		// TODO 库中支付状态接受到通知更新后，不继续后面的逻辑，或者不管，支付宝主动推送通知到成功为止即可
		// 获取支付宝POST过来反馈信息
		Map<String, String> params = new HashMap<String, String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}

		if (AlipayNotify.verify(params)) {// 验证成功

			if (trade_status.equals(PayStatus.TRADE_FINISHED.name())) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				// 如果有做过处理，不执行商户的业务程序
				notifyHandlerl(PayStatus.TRADE_FINISHED);
				// 注意：
				// 退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
			}
			if (trade_status.equals(PayStatus.TRADE_SUCCESS.name())) {
				// 判断该笔订单是否在商户网站中已经做过处理
				// 如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				// 请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				// 如果有做过处理，不执行商户的业务程序
				notifyHandlerl(PayStatus.TRADE_SUCCESS);

				// 注意：
				// 付款完成后，支付宝系统发送该交易状态通知
			}

			if (trade_status.equals(PayStatus.TRADE_CLOSED.name())) {
				notifyHandlerl(PayStatus.TRADE_CLOSED);
			}

			if (trade_status.equals(PayStatus.TRADE_PENDING.name())) {
				notifyHandlerl(PayStatus.TRADE_PENDING);
			}

			if (trade_status.equals(PayStatus.WAIT_BUYER_PAY.name())) {
				notifyHandlerl(PayStatus.WAIT_BUYER_PAY);
			}

			res.getWriter().print("success");// 请不要修改或删除

		} else {// 验证失败
			notifyHandlerl(null);
			res.getWriter().print("fail");
		}
	}
}
